﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using Estructuras.Estructura;
using Estructuras.Comunes;

namespace Estructuras.Consola.ConsolaAnalizarDatos
{
    public class ConsolaAnalizarDatos
    {
        static int Main(string[] args)
        {
            try
            {
                List<long> filasProcesadas;
                Console.Error.WriteLine(Constantes.MensajeComponente + CAnalizarDatos.NodoRaiz);
                Console.Error.WriteLine(Constantes.MensajeInicio + DateTime.Now.ToLocalTime());
                if (args.Length != 1)
                    throw new Excepcion(Constantes.ERROR_NUMERO_PARAMETROS_ENTRADA, Constantes.CODIGO_ERROR_NUMERO_PARAMETROS_ENTRADA);

                PAnalizarDatos propiedades = new PAnalizarDatos();
                propiedades.leer(args[0]);

                ObtenerElementos elementos = new ObtenerElementos();

                // Obtiene el origen de los datos
                TextReader entrada = elementos.ObtenerOrigenDatos(propiedades.Entrada);

                // Obtiene el destino de los datos
                TextWriter salida = elementos.ObtenerDestinoDatos(propiedades.Salida);

                // Obtiene el destino de los datos no encontrados
                TextWriter salidaDatos = elementos.ObtenerDestinoDatos(propiedades.SalidaPalabrasNoEncontradas);

                // Obtiene el destino de los registros no encontrados
                TextWriter salidaRegistros = elementos.ObtenerDestinoDatos(propiedades.SalidaPatronesNoEncontrados);

                // Obtiene la estructura de entrada de los datos
                Estructura.Estructura formatoEntrada = elementos.ObtenerEstructura(propiedades.EstructuraEntrada);

                // Obtiene la estructura de salida de los datos
                Estructura.Estructura formatoSalida = elementos.ObtenerEstructura(propiedades.EstructuraSalida);

                // Definición de datos
                PDefinicionDatos defDatos = new PDefinicionDatos();
                defDatos.leer(propiedades.DefinicionDatos);

                // Definición de registros
                PDefinicionRegistro defRegistros = new PDefinicionRegistro();
                defRegistros.leer(propiedades.DefinicionRegistros);

                try
                {
                    filasProcesadas = Estructuras.Funciones.Analizar.AnalizarDatos.Analizar(entrada, salida, salidaDatos, salidaRegistros,
                        defDatos.DiccionarioValores, defDatos.DiccionarioMascaras, defRegistros.DiccionarioPatrones,
                        propiedades.DiccionarioAliasCampos, propiedades.ListaCamposAnalizar, propiedades.ListaSeparadores,
                        propiedades.ListaCaracteresEspeciales, propiedades.ListaDatosEliminar, propiedades.DiccionarioDatosModificar,
                        formatoEntrada, formatoSalida);
                }
                catch (Excepcion ex)
                {
                    throw new Excepcion(Constantes.ERROR_EJECUCION + ex.Message, ex, ex.Codigo);
                }
                catch (Exception ex)
                {
                    throw new Excepcion(Constantes.ERROR_EJECUCION + ex.Message, ex, Constantes.CODIGO_ERROR_EJECUCION);
                }

                // Cierra los ficheros de entrada y salida
                elementos.CerrarOrigenDatos(entrada);
                
                elementos.CerrarDestinoDatos(salidaRegistros);
                elementos.nombreFicheroSalida = propiedades.SalidaPalabrasNoEncontradas;
                elementos.CerrarDestinoDatos(salidaDatos);
                elementos.nombreFicheroSalida = propiedades.Salida;
                elementos.CerrarDestinoDatos(salida);
                Console.Error.WriteLine(Constantes.MensajeFin + DateTime.Now.ToLocalTime());
                Console.Error.WriteLine(Constantes.MensajeRegistrosTotales + filasProcesadas[0].ToString());
                Console.Error.WriteLine(filasProcesadas[1].ToString() + Constantes.MensajeDatosNoCoincidenLista);
                Console.Error.WriteLine(filasProcesadas[2].ToString() + Constantes.MensajeRegistrosNoCoincidenLista);
                return Constantes.EJECUCION_OK;
            }
            catch (Excepcion ex)
            {
                Console.Error.WriteLine(ex.Message);
                return ex.Codigo;
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.Message);
                return Constantes.EJECUCION_ERROR;
            }
        }
    }
}
